package com.github.codemperor.gateway.fitler;

import com.github.codemperor.api.base.BaseCodeEnum;
import com.github.codemperor.core.logger.DefaultLogger;
import com.github.codemperor.core.token.CurrentUserInfo;
import com.github.codemperor.core.token.context.CurrentUserContext;
import com.github.codemperor.gateway.config.BaseFilter;
import com.github.codemperor.gateway.config.ZuulConstants;
import com.github.codemperor.gateway.context.FilterContext;
import com.netflix.zuul.context.RequestContext;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import static com.github.codemperor.core.token.HeaderConst.*;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

/**
 * @author codemperor
 * @description 这里过滤本次请求是否通过，也可以过滤请求次数、限流等等
 */
@Component
public class EndingFilter extends BaseFilter {
    private DefaultLogger log = DefaultLogger.logger(this.getClass());

    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return ZuulConstants.END_FILTER;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext currentContext = RequestContext.getCurrentContext();
        CurrentUserInfo user = FilterContext.currentUserInfo.get();

        //logger
        CurrentUserContext.set(user); // logger sdk需要从其中获取信息
        log.info("[Gateway EndingFilter] user: {}", user);

        //查看是否有异常
        BaseCodeEnum e = FilterContext.endingException.get();
        if (null != e) {
            stopAndGoLogin(currentContext, e);
            return null;
        }

        //设置header
        putHeader(currentContext, HEADER_REQUEST_NO, user.getRequestNo());
        putHeader(currentContext, HEADER_SPAN_ID, user.getSpanId());
        putHeader(currentContext, HEADER_PARENT_SPAN_ID, user.getParentSpanId());
        putHeaderEncoder(currentContext, HEADER_USER_ID, user.getUserId());
        putHeaderEncoder(currentContext, HEADER_USER_NAME, user.getUserName());
        putHeader(currentContext, HEADER_USER_EMAIL, user.getUserEmail());
        putHeader(currentContext, HEADER_USER_ROLE, user.getUserRole() == null ? "" : String.join(",", user.getUserRole()));
        putHeader(currentContext, HEADER_USER_IP, user.getRemoteHostAddress());
        putHeader(currentContext, HEADER_USER_URI, user.getUri());
        putHeader(currentContext, HEADER_USER_URI_METHOD, user.getMethod());

        return null;
    }

    private void putHeader(RequestContext currentContext, String key, String val) {
        if (!StringUtils.isEmpty(val)) {
            currentContext.addZuulRequestHeader(key, val);
        }
    }

    private void putHeaderEncoder(RequestContext currentContext, String key, String val) {
        if (!StringUtils.isEmpty(val)) {
            try {
                currentContext.addZuulRequestHeader(key, URLEncoder.encode(val, "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                log.error("", e);
            }
        }
    }
}
